﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using Dapper;
using System.Text.RegularExpressions;
using System.Data;
using _180FrameWork.DataBaseHelper.Entities;

namespace _180FrameWork.DataBaseHelper
{
    public abstract class JintDB : IJintDB
    {
        protected Database _db;

        private DbConnection _Conn;

        protected DbConnection Conn
        {
            get
            {
                if (_Conn == null)
                    _Conn = this._db.CreateConnection();
                return this._Conn;
            }
        }      

        protected string _paramChar = "";

        public dynamic Find(string sql)
        {
            return this.Conn.Query(sql).FirstOrDefault();
        }

        public dynamic Find(string sql, IDictionary<string, object> param)
        {
            return this.Conn.Query(sql, GetParams(sql, param, false)).FirstOrDefault();
        }

        public dynamic Find(string sql, IDictionary<string, object> param, System.Data.IDbTransaction tran)
        {
            return this.Conn.Query(sql, GetParams(sql, param, false), tran).FirstOrDefault();
        }

        public dynamic Find(string sql, IDictionary<string, object> param, System.Data.IDbTransaction tran, string format)
        {
            var obj = this.Conn.Query(sql, GetParams(sql, param, false), tran).FirstOrDefault();
            if (format != null && format != "")
            {
                return ConvertProps(obj, format);
            }
            else
            {
                return obj;
            }
        }

        public IList<dynamic> Query(string sql)
        {
            return this.Conn.Query(sql).ToList();
        }

        public IList<dynamic> Query(string sql, IDictionary<string, object> param)
        {
            return this.Conn.Query(sql, GetParams(sql, param, false)).ToList();
        }

        public IList<dynamic> Query(string sql, IDictionary<string, object> param, System.Data.IDbTransaction tran)
        {
            return this.Conn.Query(sql, GetParams(sql, param, false), tran).ToList();
        }

        public IList<dynamic> Query(string sql, IDictionary<string, object> param, System.Data.IDbTransaction tran, string format)
        {
            var list = this.Conn.Query(sql, GetParams(sql, param, false), tran).ToList();
            if (format != null && format != "")
            {
                var newList = new List<dynamic>();
                foreach (var obj in list)
                {
                    newList.Add(ConvertProps(obj, format));
                }
                return newList;
            }
            else
            {
                return list;
            }
        }

        public PageData<dynamic> Page(string sql)
        {
            return Page(sql, new Dictionary<string, object>(),null);
        }

        public PageData<dynamic> Page(string sql, IDictionary<string, object> param) {
            return Page(sql, param, null);
        }
        /// <summary>
        /// 分页操作，不同数据库的分页写法不一样，需要抽象重构
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        public abstract PageData<dynamic> Page(string sql, IDictionary<string, object> param, IDbTransaction tran);

        public PageData<dynamic> Page(string sql, IDictionary<string, object> param, IDbTransaction tran, string format)
        {
            var page = Page(sql, param, tran);
            if (format != null && format != "")
            {
                var newPage = new PageData<dynamic>();
                var rows = new List<dynamic>();
                foreach (var obj in page.rows)
                {
                    rows.Add(ConvertProps(obj, format));
                }
                newPage.rows = rows;
                var footer = new List<dynamic>();
                foreach (var obj in page.footer)
                {
                   footer.Add(ConvertProps(obj, format));
                }
                newPage.footer = footer;
                newPage.total = page.total;
                newPage.totalPages = page.totalPages;
                return newPage;
            }
            else
            {
                return page;
            }
        }

        /// <summary>
        /// 查询表格
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public GridData<dynamic> Grid(string sql) { return Grid(sql, new Dictionary<string, object>()); }
        /// <summary>
        /// 查询表格
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public GridData<dynamic> Grid(string sql, IDictionary<string, object> param)
        {
            string sort = ""; string order = ""; string SUM = "";
            foreach (KeyValuePair<string, object> item in param)
            {
                switch (item.Key)
                {
                    case "sort":
                        sort = Convert.ToString(item.Value);
                        break;
                    case "order":
                        order = Convert.ToString(item.Value);
                        break;
                    case "sum":
                        SUM = Convert.ToString(item.Value);
                        break;
                    //default:
                    //    dp.Add(item.Key, item.Value);
                    //    break;
                }
            }
            var dp = GetParams(sql, param, false);
            var p = new GridData<dynamic>();

            //汇总
            if (SUM != "")
            {
                string strSumSql = "select " + SUM + " from(" + sql + ") t";
                p.footer = this.Conn.Query(strSumSql, dp).ToList();
            }
            //排序
            string orderby = "";
            if (sort != "")
            {
                orderby = " order by " + sort;
                if (order != "")
                {
                    orderby += " " + order;
                }
            }
            p.rows = this.Conn.Query(sql, dp).ToList();
            return p;
        }

        public int Exec(string sql)
        {
            return this.Conn.Execute(sql);
        }

        public int Exec(string sql, IDictionary<string, object> param)
        {
            return this.Conn.Execute(sql, GetParams(sql, param, false));
        }

        public int Exec(string sql, IDictionary<string, object> param, System.Data.IDbTransaction tran)
        {
            return this.Conn.Execute(sql, GetParams(sql, param, false), tran);
        }

        public abstract IDictionary<string, object> Sp(string spName, IDictionary<string, object>[] param);

        public System.Data.IDbTransaction BeginTran()
        {           
            return this.Conn.BeginTransaction();
        }

        public void Open()
        {
            this.Conn.Open();
        }

        public void Close()
        {
            this.Conn.Close();
        }

        public IList<string> Match(string SQL, IDictionary<string, object> param)
        {
            IList<string> NoMatchList = new List<string>();
            if (this._paramChar != "")
            {
                var mapList = Regex.Matches(SQL, @"\" + this._paramChar + @"\w+").Cast<Match>().Select(m => m.Value).Distinct().ToArray();
                foreach (var p in mapList)
                {
                    string key = p.Replace(this._paramChar, "");
                    bool IsExist = false;
                    foreach (KeyValuePair<string, object> prop in param)
                    {
                        if (prop.Key.ToUpper() == key.ToUpper())
                        {
                            IsExist = true;
                            break;
                        }
                    }
                    if (!IsExist)
                    {
                        NoMatchList.Add(key);
                    }
                }
            }
            return NoMatchList;
        }

        public void ChangeDatabase(string databaseName)
        {
            if (this._Conn == null)
            {
            }
            else
            {
                if (this._Conn.State == ConnectionState.Open)
                    this._Conn.Close();
            }
            this._db = new Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase(databaseName);
            //同时将数据库链接制空，否则会影响使用 2020-2-6 by lins
            this._Conn = null;
        }

        protected abstract DynamicParameters GetParams(string SQL, IDictionary<string, object> data, bool StrToDateTime);

        #region ORM扩展

        private IDictionary<string, DataBaseTableSchedule> _catchList;

        private IDictionary<string, DataBaseTableSchedule> catchList
        {
            get
            {
                if (this._catchList == null)
                {
                    this._catchList = new Dictionary<string, DataBaseTableSchedule>();
                }
                return this._catchList;
            }
        }

        object locker = new object();

        public IList<string> MatchInsert(string tableName, IDictionary<string, object> data)
        {
            string sql = GetInsertSQL(tableName, data, null);
            return this.Match(sql, data);
        }

        public IList<string> MatchInsert(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            string sql = GetInsertSQL(tableName, data, tran);
            return this.Match(sql, data);
        }

        public IList<string> MatchUpdate(string tableName, IDictionary<string, object> data)
        {
            string sql = GetUpdateSQL(tableName, data, null);
            return this.Match(sql, data);
        }

        public IList<string> MatchUpdate(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            string sql = GetUpdateSQL(tableName, data, tran);
            return this.Match(sql, data);
        }

        private DataBaseTableSchedule getDataBaseTableSchedule(string tableName, IDbTransaction tran)
        {
            lock (locker)
            {
                DataBaseTableSchedule schedule = null;
                if (this.catchList.ContainsKey(tableName))
                {
                    schedule = this.catchList[tableName];
                }
                else
                {
                    schedule = GetTableSchedule(tableName, tran);
                    this.catchList.Add(tableName, schedule);
                }
                return schedule;
            }
        }

        /// <summary>
        /// 获取查找SQL语句
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        private string GetSelectSQL(string tableName, IDbTransaction tran)
        {
            //根据表名获取结构
            var schedule = getDataBaseTableSchedule(tableName, tran);
            StringBuilder strSQL = new StringBuilder();
            strSQL.AppendFormat("select * from {0} where 1=1", tableName);
            var pklist = schedule.PrimaryKeyList;
            foreach (var key in pklist)
            {
                strSQL.AppendFormat(" and {0}=" + _paramChar + "{0}", key.ColumnName);
            }
            return strSQL.ToString();
        }
        /// <summary>
        /// 获取插入SQL语句
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private string GetInsertSQL(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            //根据表名获取结构
            var schedule = getDataBaseTableSchedule(tableName, tran);
            StringBuilder strSQL = new StringBuilder();
            strSQL.AppendFormat("insert into {0}(", tableName);
            foreach (var item in data)
            {
                foreach (var col in schedule.ColumnList)
                {
                    if (item.Key.ToUpper() == col.ColumnName.ToUpper())
                    {
                        strSQL.Append(item.Key + ",");
                    }
                }
                //if (item.Value != null)
                //{
                //    switch (item.Value.GetType().Name.ToString().ToUpper())
                //    {
                //        case "STRING":
                //        case "DATETIME":
                //        case "DOUBLE":
                //        case "BOOL":
                //            strSQL.Append(item.Key + ",");
                //            break;
                //    }
                //}
            }
            strSQL.Remove(strSQL.Length - 1, 1);
            strSQL.Append(")values(");
            foreach (var item in data)
            {
                foreach (var col in schedule.ColumnList)
                {
                    if (item.Key.ToUpper() == col.ColumnName.ToUpper())
                    {
                        strSQL.Append(this._paramChar + item.Key + ",");
                    }
                }
                //if (item.Value != null)
                //{
                //    switch (item.Value.GetType().Name.ToString().ToUpper())
                //    {
                //        case "STRING":
                //        case "DATETIME":
                //        case "DOUBLE":
                //        case "BOOL":
                //            strSQL.Append(this._paramChar + item.Key + ",");
                //            break;
                //    }
                //}
            }
            strSQL.Remove(strSQL.Length - 1, 1);
            strSQL.Append(")");
            return strSQL.ToString();
        }
        /// <summary>
        /// 获取更新SQL语句
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="data"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        private string GetUpdateSQL(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            //根据表名获取结构
            var schedule = getDataBaseTableSchedule(tableName, tran);
            StringBuilder strSQL = new StringBuilder();

            //根据表名获取主键
            var pklist = schedule.PrimaryKeyList;
            var collist = schedule.ColumnNoPrimaryKeyList;
            if (pklist != null && pklist.Count > 0)
            {
                if (data != null && data.Count > 0)
                {
                    strSQL.AppendFormat("update {0} set ", tableName);

                    foreach (var item in data)
                    {
                        foreach (var col in schedule.ColumnNoPrimaryKeyList)
                        {
                            if (col.ColumnName.ToUpper() == item.Key.ToUpper())
                            {
                                strSQL.Append(item.Key + "=" + this._paramChar + item.Key + ",");
                            }
                        }
                    }
                    strSQL.Remove(strSQL.Length - 1, 1);
                    strSQL.Append(" where 1=1 ");
                    foreach (var pk in pklist)
                    {
                        strSQL.Append(" and " + pk.ColumnName + "=" + this._paramChar + pk.ColumnName + "");
                    }
                    return strSQL.ToString();
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 获取删除SQL语句
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="data"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        private string GetDeleteSQL(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            //根据表名获取结构
            var schedule = getDataBaseTableSchedule(tableName, tran);
            StringBuilder strSQL = new StringBuilder();
            //根据表名获取主键
            var pklist = schedule.PrimaryKeyList;
            if (pklist != null && pklist.Count > 0)
            {
                if (data != null && data.Count > 0)
                {
                    strSQL.AppendFormat("delete from {0} where 1=1 ", tableName);
                    foreach (var pk in pklist)
                    {
                        strSQL.Append(" and " + pk.ColumnName + "=" + this._paramChar + pk.ColumnName + "");
                    }
                    return strSQL.ToString();
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 获取主键
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        //protected abstract IList<string> GetPKList(string tableName, IDbTransaction tran);
        /// <summary>
        /// 获取表结构
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        protected abstract DataBaseTableSchedule GetTableSchedule(string tableName, IDbTransaction tran);
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public dynamic Get(string tableName, IDictionary<string, object> param)
        {
            string sql = GetSelectSQL(tableName, null);
            return this.Conn.Query(sql, GetParams(sql, param, true)).FirstOrDefault();
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="param"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        public dynamic Get(string tableName, IDictionary<string, object> param, IDbTransaction tran)
        {
            string sql = GetSelectSQL(tableName, tran);
            return this.Conn.Query(sql, GetParams(sql, param, true), tran).FirstOrDefault();
        }

        public dynamic Get(string tableName, IDictionary<string, object> param, IDbTransaction tran, string format)
        {
            string sql = GetSelectSQL(tableName, tran);
            var obj = this.Conn.Query(sql, GetParams(sql, param, true), tran).FirstOrDefault();
            if (format != null && format != "")
            {
                return ConvertProps(obj, format);
            }
            else
            {
                return obj;
            }
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public int Insert(string tableName, IDictionary<string, object> data)
        {
            string sql = GetInsertSQL(tableName, data, null);
            return this.Conn.Execute(sql, GetParams(sql, data, true));
        }
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="param"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        public int Insert(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            string sql = GetInsertSQL(tableName, data, tran);
            return this.Conn.Execute(sql, GetParams(sql, data, true), tran);
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="data"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public int Update(string tableName, IDictionary<string, object> data)
        {
            string sql = GetUpdateSQL(tableName, data, null);
            return this.Conn.Execute(sql, GetParams(sql, data, true));
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="data"></param>
        /// <param name="param"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        public int Update(string tableName, IDictionary<string, object> data, IDbTransaction tran)
        {
            string sql = GetUpdateSQL(tableName, data, tran);
            return this.Conn.Execute(sql, GetParams(sql, data, true), tran);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public int Delete(string tableName, IDictionary<string, object> param)
        {
            string sql = GetDeleteSQL(tableName, param, null);
            return this.Conn.Execute(sql, GetParams(sql, param, true), null);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="param"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        public int Delete(string tableName, IDictionary<string, object> param, IDbTransaction tran)
        {
            string sql = GetDeleteSQL(tableName, param, tran);
            return this.Conn.Execute(sql, GetParams(sql, param, true), tran);
        }

        #endregion

        #region base64支持
        /// <summary>  
        /// 是否base64字符串  
        /// </summary>  
        /// <param name="base64Str">要判断的字符串</param>  
        /// <param name="bytes">字符串转换成的字节数组</param>  
        /// <returns></returns>  
        protected bool IsBase64(string base64Str, out byte[] bytes)
        {
            //string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";  
            bytes = null;
            if (string.IsNullOrEmpty(base64Str))
                return false;
            else
            {
                if (base64Str.Contains(","))
                    base64Str = base64Str.Split(',')[1];
                if (base64Str.Length % 4 != 0)
                    return false;
                if (base64Str.Any(c => !base64CodeArray.Contains(c)))
                    return false;
            }
            try
            {
                bytes = Convert.FromBase64String(base64Str);
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }
        protected static char[] base64CodeArray = new char[]  
        {  
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',  
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',  
            '0', '1', '2', '3', '4',  '5', '6', '7', '8', '9', '+', '/', '='  
        };
        #endregion

        #region 日期格式支持
        /// <summary>
        /// 是否日期时间格式
        /// </summary>
        /// <param name="dateStr"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        protected bool IsDateTime(string dateStr, out DateTime dt)
        {
            if (IsTime(dateStr))
            {
                dt = DateTime.Now;
                return false;
            }
            else
            {
                string[] format = { 
                                      "yyyy-MM-dd", 
                                      "yyyy-M-d", 
                                      "yyyy-M-dd", 
                                      "yyyy-MM-d", 
                                      "yyyy-MM-dd HH:mm:ss",
                                      "yyyy-M-dd HH:mm:ss",
                                      "yyyy-M-d HH:mm:ss",
                                      "yyyy-MM-d HH:mm:ss",
                                      "yyyy-MM-dd HH:mm",
                                      "yyyy-M-dd HH:mm",
                                      "yyyy-M-d HH:mm",
                                      "yyyy-MM-d HH:mm"
                                  };
                return DateTime.TryParseExact(dateStr, format, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt);
            }
        }

        
        /// <summary>
        /// 是否为日期型字符串
        /// </summary>
        /// <param name="StrSource">日期字符串(2008-05-08)</param>
        /// <returns></returns>
        private bool IsDate(string StrSource)
        {
            return Regex.IsMatch(StrSource, @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-9]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");
        }

        /// <summary>
        /// 是否为时间型字符串
        /// </summary>
        /// <param name="source">时间字符串(15:00)</param>
        /// <returns></returns>
        private bool IsTime(string StrSource)
        {
            return Regex.IsMatch(StrSource, @"^((20|21|22|23|[0-1]?\d):[0-5]?\d)$");
        }

        /// <summary>
        /// 是否为日期+时间型字符串
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private bool IsDateTime(string StrSource)
        {
            return Regex.IsMatch(StrSource, @"^(((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d)$");
        }

        /// <summary>
        /// 是否为日期+时间型字符串
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private bool IsDateTime1(string StrSource)
        {
            return Regex.IsMatch(StrSource, @"^(((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d)$");
        }   
        #endregion
       

        #region 字段格式转换
        private static IDictionary<string, object> ConvertProps(IDictionary<string, object> obj, string ConverType)
        {
            if (obj == null)
            {
                return null;
            }
            else
            {
                var result = new Dictionary<string, object>();
                foreach (var key in obj.Keys)
                {
                    switch (ConverType)
                    {
                        case "lower":
                            result.Add(key.ToLower(), obj[key]);
                            break;
                        case "upper":
                            result.Add(key.ToUpper(), obj[key]);
                            break;
                        case "under":
                            result.Add(camel2under(key), obj[key]);
                            break;
                        case "camel":
                            result.Add(under2camel(key), obj[key]);
                            break;
                    }
                }
                return result;
            }
        }
        #endregion

        #region 驼峰大写转换
        private static string camel2under(string c)
        {
            StringBuilder strValue = new StringBuilder();
            for (var j = 0; j < c.Length; j++)
            {
                string temp = c[j].ToString();
                if (Regex.IsMatch(temp, "[A-Z]"))
                {
                    if (strValue.Length == 0)
                    {

                    }
                    else
                    {
                        temp = "_" + temp;
                    }
                }
                strValue.Append(temp);
            }
            return strValue.ToString().ToUpper();
        }

        private static string under2camel(string s)
        {
            StringBuilder strValue = new StringBuilder();
            var list = s.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var word in list)
            {
                strValue.Append(word.Substring(0, 1).ToUpper() + word.Substring(1).ToLower());
            }
            return strValue.ToString();
        }
        #endregion

      
    }
}
